package gui.panels;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.awt.Point;

import javax.swing.JPanel;
import geo.obj.PhiObject;

public class ObjectDrawPanel extends JPanel implements MouseListener, MouseMotionListener {
	
	private static final long serialVersionUID = 1L;
	private PhiObject _p;
	private boolean _c = false;
	private ArrayList<Point> _points = new ArrayList<Point>();
	private int _clickCount = 0;
	private boolean _pole = false;
	private Point _ple = new Point();
	
	public ObjectDrawPanel(){
		super();
		addMouseListener(this);
		addMouseMotionListener(this);
	}
	
	public ObjectDrawPanel(PhiObject p){
		_p = p;
	}
	
	public void paint(Graphics g){
		g.setColor(Color.WHITE);
		g.fillRect(0, 0, getWidth(), getHeight());
		g.setColor(Color.BLACK);
		
		if(_c){
			g.drawLine(_points.get(0).x, _points.get(0).y, _points.get(_points.size() - 1).x, _points.get(_points.size() - 1 ).y);
		}
		
		drawpole(g);
		drawpoints(g);
		drawlines(g);
	}
	
	public void drawpole(Graphics g){
		if (_pole){
			int x[] = new int[4];
			int y[] = new int[4];
			
			x[0] = _ple.x - 2;
			y[0] = _ple.y - 2;
			
			x[1] = _ple.x + 2;
			y[1] = _ple.y - 2;
			
			x[2] = _ple.x + 2;
			y[2] = _ple.y + 2;
			
			x[3] = _ple.x - 2;
			y[3] = _ple.y + 2;
			
			g.setColor(Color.RED);
			Polygon p = new Polygon(x,y,4);
			g.drawPolygon(p);
			g.setColor(Color.BLACK);
			_pole = false;
		}
	}

	public void connect() {
		_c = true;
		repaint();
	}

	@Override
	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseMoved(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent me) {
		if (!_c){
			
			boolean doubleclick = false;
			for(int i = 0; i < _points.size(); i++){
				int x[] = new int[4];
				int y[] = new int[4];
				
				x[0] = _points.get(i).x - 2;
				y[0] = _points.get(i).y - 2;
				
				x[1] = _points.get(i).x + 2;
				y[1] = _points.get(i).y - 2;
				
				x[2] = _points.get(i).x + 2;
				y[2] = _points.get(i).y + 2;
				
				x[3] = _points.get(i).x - 2;
				y[3] = _points.get(i).y + 2;
				
				Polygon p = new Polygon(x, y, 4);
				
				if (p.contains(me.getPoint())) doubleclick = true;
			}
			if(!doubleclick){
				_clickCount++;
				_points.add(me.getPoint());
				repaint();
			}
		}
		if (_pole){
			_ple = me.getPoint();
			revalidate();
			repaint();	
			
			
		}
		
		
	}
	
	public boolean state(){
		if (_clickCount >= 3 && isConvex()){
			return true;
		}
		return false;
	}
	
	public boolean clickstate(){
		if (_clickCount >= 3){
			return true;
		}
		return false;
	}
	
	public void setPole(){
		_pole = true;
	}
	
	private void drawpoints (Graphics g){
		for(int i = 0; i < _points.size(); i++){
			int x[] = new int[4];
			int y[] = new int[4];
			
			x[0] = _points.get(i).x - 2;
			y[0] = _points.get(i).y - 2;
			
			x[1] = _points.get(i).x + 2;
			y[1] = _points.get(i).y - 2;
			
			x[2] = _points.get(i).x + 2;
			y[2] = _points.get(i).y + 2;
			
			x[3] = _points.get(i).x - 2;
			y[3] = _points.get(i).y + 2;
		
			g.drawPolygon(x, y, 4);
		}
	}
	
	private void drawlines (Graphics g){
		for (int i = 0; i < _points.size() - 1; i++){
			g.drawLine(_points.get(i).x, _points.get(i).y, _points.get(i + 1).x, _points.get(i + 1).y);
		}
	}
	
	private boolean det(int x1, int y1, int x2, int y2, int x3,int y3){ //vector multiplication
		if ((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1) > 0) return true;
		else return false;
	}
	
	public boolean leftsided(){
		int n = 0;
		int ym = _points.get(0).y;
		for(int i = 0; i < _points.size() - 2; i++){
			if (_points.get(i).y < ym){
				ym = _points.get(i).y;
				n = i;
			}
		}
		int n1 = n - 1;
		int n2 = n + 1;
		if(n == 0) n1 = _points.size() - 1;
		if(n == _points.size() - 1) n2 = 0;
		
		if (det(_points.get(n1).x, _points.get(n1).y, _points.get(n).x, _points.get(n).y, _points.get(n2).y, _points.get(n2).y)) return true;
		return false;
	}
	
	public boolean convexState(){
		return true; //TODO
	}
	
	public boolean poleInside(){
		return true;	//TODO
	}
	
	public PhiObject getPhiObject(){
		double xm[] = new double[(_points.size())];
		double ym[] = new double[(_points.size())];
		
		for (int i = 0; i < _points.size(); i++){
			xm[i] = (double)_points.get(i).x;
			ym[i] = (double)_points.get(i).y;
		}
		
		PhiObject ppp = new PhiObject(xm, ym, _ple.x, _ple.y, 0.0);
		return ppp;
	}
	
	public boolean isConvex(){
		int lol = 0;
		for (int i = 0; i < _points.size() - 2; i++){
			if (det(_points.get(i).x, _points.get(i).y, _points.get(i+1).x, _points.get(i+1).y, _points.get(i+1).y, _points.get(i+1).y)) lol++;
		}
		
//		if (lol == _points.size() - 3 || _points.size() == 3) return true;
//		return false;
		return true;
	}
}